AWS ELB (Elastic Load Balancing)
Detailed Content
Elastic Load Balancing (ELB) automatically distributes incoming application traffic across multiple targets, such as EC2 instances, containers, IP addresses, and Lambda functions. It enables you to achieve fault tolerance in your applications, seamlessly scale your capacity, and maintain high availability.
Core Concepts
- Load Balancer: The central component of ELB. It acts as a single point of contact for clients, distributing incoming application traffic across multiple targets, such as EC2 instances, containers, IP addresses, and Lambda functions. Load balancers are highly available and automatically scale to handle varying traffic loads.
- Listeners: A process that checks for connection requests from clients, using the protocol and port that you configure. Listeners define how the load balancer routes requests to target groups. For example, an HTTP listener on port 80 will forward HTTP requests to a specified target group.
- Listener Rules: For Application Load Balancers, listener rules allow you to inspect incoming requests and route them to different target groups based on various criteria, such as the URL path, host header, HTTP method, query parameters, or source IP address. Each rule consists of a priority, one or more conditions, and one or more actions.
- Target Groups: Route requests to one or more registered targets, such as EC2 instances, using the protocol and port number that you specify. Each target group can be used with one or more listeners. Target groups are also where you configure health checks for the registered targets.
- Targets: The resources that receive traffic from the load balancer. These can be EC2 instances, IP addresses (including those outside your VPC), Lambda functions, or containers.
- Health Checks: Used by the load balancer to monitor the health and availability of its registered targets. If a target fails health checks, the load balancer stops sending traffic to it until it passes health checks again. This ensures that traffic is only sent to healthy instances, improving application reliability.
- Availability Zones: Load balancers are deployed across multiple Availability Zones to ensure high availability and fault tolerance. If one AZ becomes unhealthy, the load balancer continues to route traffic to healthy targets in other AZs.
- Cross-Zone Load Balancing: Distributes traffic evenly across all registered targets in all enabled Availability Zones. Without cross-zone load balancing, each load balancer node distributes traffic only to targets in its own AZ. Enabling it can help improve application availability and resource utilization.
- Sticky Sessions (Session Affinity): Binds a user's session to a specific target instance, ensuring that all requests from that user during the session are sent to the same instance. This is important for applications that store session state locally on the server. ALBs use application-based cookies for stickiness.
- Connection Draining (Deregistration Delay): Ensures that the load balancer stops sending new requests to a target that is de-registering or unhealthy, but keeps existing connections open for a specified duration to allow in-flight requests to complete gracefully.
- Load Balancer Logging (Access Logs): ELB can capture detailed information about requests sent to your load balancer and deliver them to an S3 bucket. These logs include information such as the time the request was received, client IP address, latencies, request paths, and server responses. Useful for traffic analysis, auditing, and troubleshooting.
Types of Load Balancers
AWS offers three modern types of load balancers, each designed for specific use cases:
-
Application Load Balancer (ALB):
- Layer: Operates at the application layer (Layer 7) of the OSI model.
- Traffic: Best suited for HTTP and HTTPS traffic.
- Features:
- Content-based Routing: Supports path-based routing (e.g.,
/usersto one target group,/productsto another), host-based routing (e.g.,api.example.comto one target group,web.example.comto another), and query string/header-based routing. - Target Types: Can route requests to EC2 instances, IP addresses, and Lambda functions.
- SSL Termination: Offloads SSL/TLS decryption from your backend servers.
- Sticky Sessions: Supports cookie-based sticky sessions.
- Integration: Integrates with AWS WAF, AWS Certificate Manager (ACM), and Amazon CloudWatch.
- Content-based Routing: Supports path-based routing (e.g.,
- Use Cases: Microservices architectures, container-based applications (ECS, EKS), web applications, and serverless applications (Lambda).
-
Network Load Balancer (NLB):
- Layer: Operates at the connection layer (Layer 4) of the OSI model.
- Traffic: Best suited for extreme performance, static IP addresses, and TCP, TLS, and UDP traffic.
- Features:
- High Performance: Handles millions of requests per second with ultra-low latency.
- Static IP Addresses: Provides a static IP address per Availability Zone, which can be useful for whitelisting or DNS configurations.
- Preserves Client IP: By default, NLB passes the client's source IP address directly to the targets.
- Target Types: Can route requests to EC2 instances and IP addresses.
- TLS Termination: Supports TLS termination at the load balancer.
- Use Cases: High-throughput, low-latency applications, gaming servers, IoT backends, and when preserving client IP is critical.
-
Gateway Load Balancer (GLB):
- Layer: Operates at Layer 3 (network layer) and Layer 4 (transport layer).
- Traffic: Used to deploy, scale, and manage virtual appliances such as firewalls, intrusion detection and prevention systems, and deep packet inspection systems.
- Features:
- Transparent Network Gateway: Acts as a single entry and exit point for all traffic, transparently passing all network traffic to and from the virtual appliances.
- GENEVE Protocol: Uses the GENEVE (Generic Network Virtualization Encapsulation) protocol to encapsulate and decapsulate traffic between the GLB and the virtual appliances.
- High Availability: Distributes traffic across a fleet of virtual appliances.
- Use Cases: Centralized inspection of network traffic, deploying third-party network virtual appliances, and creating a demilitarized zone (DMZ) for network security.
Classic Load Balancer (CLB)
- Legacy: The previous generation of load balancers. While still supported, it is not recommended for new applications.
- Layer: Operates at both Layer 4 and Layer 7.
- Features: Supports basic load balancing for HTTP/HTTPS and TCP traffic.
- Recommendation: For new applications, always choose ALB or NLB based on your specific requirements.
Interview Questions
Conceptual Questions
- What is Elastic Load Balancing (ELB) and what are its primary benefits?
- ELB is a service that automatically distributes incoming application traffic across multiple targets, such as EC2 instances, containers, IP addresses, and Lambda functions. Its primary benefits are:
- High Availability: Distributes traffic across multiple Availability Zones.
- Fault Tolerance: Automatically routes traffic away from unhealthy targets.
- Scalability: Automatically scales to handle varying traffic loads.
- Security: Integrates with VPC, Security Groups, and AWS WAF.
- ELB is a service that automatically distributes incoming application traffic across multiple targets, such as EC2 instances, containers, IP addresses, and Lambda functions. Its primary benefits are:
- Explain the different types of load balancers offered by AWS and their primary use cases.
- Application Load Balancer (ALB): Layer 7 (HTTP/HTTPS). Ideal for microservices, container-based applications, and advanced content-based routing (path, host, headers).
- Network Load Balancer (NLB): Layer 4 (TCP/UDP/TLS). Designed for extreme performance, ultra-low latency, static IP addresses, and preserving client IP. Suitable for gaming, IoT, and high-throughput workloads.
- Gateway Load Balancer (GLB): Layer 3/4. Used for deploying, scaling, and managing virtual network appliances (firewalls, IDS/IPS) transparently.
- Classic Load Balancer (CLB): Legacy (Layer 4/7). Not recommended for new applications.
- What is a Target Group in ELB and how does it work with listeners?
- A Target Group is a logical grouping of targets (e.g., EC2 instances, IP addresses) that receive traffic from a load balancer. It defines the protocol and port for routing requests to these targets and also configures health checks.
- Listeners check for incoming connection requests on a specific protocol and port. They have rules that determine which target group to forward requests to. For ALBs, listeners can have multiple rules for content-based routing to different target groups.
- How do health checks work in ELB and why are they important?
- Health checks are periodic tests performed by the load balancer to determine the operational status of registered targets. If a target fails a configured number of health checks, the load balancer marks it as unhealthy and stops sending new requests to it. This is crucial for maintaining application availability and ensuring that clients only interact with healthy instances.
- Explain Cross-Zone Load Balancing and its benefits.
- Cross-Zone Load Balancing distributes incoming traffic evenly across all registered targets in all enabled Availability Zones. Without it, each load balancer node distributes traffic only to targets in its own AZ. Benefits include improved fault tolerance (if one AZ has fewer healthy instances, traffic is still distributed across all healthy instances globally) and better resource utilization.
- What are sticky sessions (session affinity) and when would you use them?
- Sticky sessions ensure that all requests from a particular client during a session are sent to the same target instance. This is essential for applications that maintain session state on the server (e.g., shopping carts, user logins) and cannot easily share state across multiple instances. ALBs use application-based cookies for stickiness.
Scenario-Based Questions
- You have a web application that serves both static content (images, CSS) and dynamic content (API calls). You want to optimize performance, cost, and ensure high availability. Which type of load balancer would you choose and how would you configure it?
- I would choose an Application Load Balancer (ALB). I would configure listener rules to:
- Route requests for static content (e.g.,
/images/*,/css/*) to an S3 bucket (via CloudFront for caching) or a target group of instances optimized for static file serving. - Route requests for dynamic content (e.g.,
/api/*) to a target group of application servers (e.g., EC2 instances in an Auto Scaling Group). This leverages ALB's Layer 7 routing capabilities, optimizes performance by offloading static content, and ensures high availability by distributing dynamic traffic across multiple instances in different AZs.
- Route requests for static content (e.g.,
- I would choose an Application Load Balancer (ALB). I would configure listener rules to:
- You need to expose a high-performance, low-latency gaming server that uses TCP traffic to the internet. The server requires the client's original IP address for anti-cheat and logging purposes. Which type of load balancer would be most suitable and why?
- I would choose a Network Load Balancer (NLB). NLB operates at Layer 4, supports TCP traffic, and is designed for extreme performance and ultra-low latency, which is critical for gaming. Crucially, NLB preserves the client's source IP address by default, passing it directly to the targets, which fulfills the requirement for anti-cheat and logging.
- Your application has a fleet of microservices, some running on EC2 instances and others as Lambda functions. You need a single entry point for clients and the ability to route requests to the appropriate microservice based on the URL path. How would you achieve this?
- I would use an Application Load Balancer (ALB). I would create multiple target groups: one for the EC2 instances and another for the Lambda functions. Then, I would configure listener rules on the ALB to route requests based on the URL path. For example, requests to
/users/*could go to the Lambda target group, while requests to/products/*could go to the EC2 instance target group. This provides a unified API endpoint and leverages ALB's content-based routing capabilities.
- I would use an Application Load Balancer (ALB). I would create multiple target groups: one for the EC2 instances and another for the Lambda functions. Then, I would configure listener rules on the ALB to route requests based on the URL path. For example, requests to
- You are performing maintenance on a set of backend servers registered with your load balancer. You want to gracefully remove these servers from service without dropping active connections. How would you do this?
- I would use Connection Draining (Deregistration Delay). When I de-register the instances from the target group, the load balancer will stop sending new requests to them but will keep existing connections open for a configurable period (e.g., 300 seconds). This allows in-flight requests to complete gracefully before the instances are terminated or taken offline for maintenance, preventing service disruption for active users.
Coding/CLI Examples
Here are some common ELB operations using the AWS CLI and Python (Boto3).
AWS CLI Examples
-
Create an Application Load Balancer (ALB) with an HTTP listener and a target group: ```bash # Replace with your actual VPC ID, Subnet IDs, and Security Group ID VPC_ID="vpc-0abcdef1234567890" SUBNET_ID_1="subnet-0abcdef1234567890" SUBNET_ID_2="subnet-0fedcba9876543210" SECURITY_GROUP_ID="sg-0abcdef1234567890"
1. Create a Load Balancer
LB_ARN=$(aws elbv2 create-load-balancer \ --name my-alb-cli \ --subnets $SUBNET_ID_1 $SUBNET_ID_2 \ --security-groups $SECURITY_GROUP_ID \ --scheme internet-facing \ --type application \ --query 'LoadBalancers[0].LoadBalancerArn' --output text) echo "Created ALB ARN: $LB_ARN"
2. Create a Target Group
TG_ARN=$(aws elbv2 create-target-group \ --name my-app-tg-cli \ --protocol HTTP \ --port 80 \ --vpc-id $VPC_ID \ --health-check-protocol HTTP \ --health-check-path /health \ --health-check-interval-seconds 30 \ --health-check-timeout-seconds 5 \ --healthy-threshold-count 2 \ --unhealthy-threshold-count 2 \ --query 'TargetGroups[0].TargetGroupArn' --output text) echo "Created Target Group ARN: $TG_ARN"
3. Create a Listener for HTTP on port 80
aws elbv2 create-listener \ --load-balancer-arn $LB_ARN \ --protocol HTTP \ --port 80 \ --default-actions Type=forward,TargetGroupArn=$TG_ARN echo "Created HTTP Listener."
Get ALB DNS Name
LB_DNS_NAME=$(aws elbv2 describe-load-balancers --load-balancer-arns $LB_ARN --query 'LoadBalancers[0].DNSName' --output text) echo "ALB DNS Name: $LB_DNS_NAME" ```
-
Register an EC2 instance with a target group: ```bash # Replace with your actual Target Group ARN and EC2 Instance ID TARGET_GROUP_ARN="arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-app-tg-cli/50dc6c495c0c9188" EC2_INSTANCE_ID="i-0abcdef1234567890"
aws elbv2 register-targets \ --target-group-arn $TARGET_GROUP_ARN \ --targets Id=$EC2_INSTANCE_ID echo "Registered instance $EC2_INSTANCE_ID with target group $TARGET_GROUP_ARN" ```
-
Configure path-based routing on an ALB listener: ```bash # Replace with your actual Listener ARN and Target Group ARNs LISTENER_ARN="arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/app/my-alb-cli/50dc6c495c0c9188/f2f7dc8efc522ab2" WEB_TG_ARN="arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-web-tg/50dc6c495c0c9188" API_TG_ARN="arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-api-tg/50dc6c495c0c9188"
Create a rule to forward /api/* to API Target Group
aws elbv2 create-listener-rule \ --listener-arn $LISTENER_ARN \ --priority 10 \ --conditions Field=path-pattern,Values='/api/' \ --actions Type=forward,TargetGroupArn=$API_TG_ARN echo "Created path-based rule for /api/"
Modify the default action to forward all other traffic to Web Target Group
aws elbv2 modify-listener \ --listener-arn $LISTENER_ARN \ --default-actions Type=forward,TargetGroupArn=$WEB_TG_ARN echo "Modified default listener action." ```
Python (Boto3) Examples
First, ensure you have Boto3 installed (pip install boto3) and your AWS credentials configured.
-
Create an Application Load Balancer (ALB) and a Target Group: ```python import boto3
elbv2_client = boto3.client('elbv2') ec2_client = boto3.client('ec2')
vpc_id = "vpc-0abcdef1234567890" # REPLACE with your VPC ID subnet_ids = ["subnet-0abcdef1234567890", "subnet-0fedcba9876543210"] # REPLACE with your Subnet IDs security_group_id = "sg-0abcdef1234567890" # REPLACE with your Security Group ID
alb_name = "my-boto3-alb" tg_name = "my-boto3-app-tg"
try: # 1. Create ALB alb_response = elbv2_client.create_load_balancer( Name=alb_name, Subnets=subnet_ids, SecurityGroups=[security_group_id], Scheme='internet-facing', Type='application', Tags=[ {'Key': 'Name', 'Value': alb_name} ] ) alb_arn = alb_response['LoadBalancers'][0]['LoadBalancerArn'] print(f"Created ALB: {alb_arn}")
# 2. Create Target Group tg_response = elbv2_client.create_target_group( Name=tg_name, Protocol='HTTP', Port=80, VpcId=vpc_id, HealthCheckProtocol='HTTP', HealthCheckPath='/health', HealthCheckIntervalSeconds=30, HealthCheckTimeoutSeconds=5, HealthyThresholdCount=2, UnhealthyThresholdCount=2, Tags=[ {'Key': 'Name', 'Value': tg_name} ] ) tg_arn = tg_response['TargetGroups'][0]['TargetGroupArn'] print(f"Created Target Group: {tg_arn}") # 3. Create Listener listener_response = elbv2_client.create_listener( LoadBalancerArn=alb_arn, Protocol='HTTP', Port=80, DefaultActions=[ { 'Type': 'forward', 'TargetGroupArn': tg_arn }, ] ) listener_arn = listener_response['Listeners'][0]['ListenerArn'] print(f"Created Listener: {listener_arn}")except Exception as e: print(f"Error creating ELB resources: {e}") ```
-
Register an EC2 instance with a Target Group: ```python import boto3
elbv2_client = boto3.client('elbv2')
target_group_arn = "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/my-boto3-app-tg/a1b2c3d4e5f6g7h8" # REPLACE with your Target Group ARN instance_id = "i-0abcdef1234567890" # REPLACE with your EC2 Instance ID
try: elbv2_client.register_targets( TargetGroupArn=target_group_arn, Targets=[ { 'Id': instance_id, 'Port': 80 # Port on the instance }, ] ) print(f"Registered instance {instance_id} with target group {target_group_arn}") except Exception as e: print(f"Error registering target: {e}") ```
-
Create a Network Load Balancer (NLB): ```python import boto3
elbv2_client = boto3.client('elbv2')
vpc_id = "vpc-0abcdef1234567890" # REPLACE with your VPC ID subnet_ids = ["subnet-0abcdef1234567890", "subnet-0fedcba9876543210"] # REPLACE with your Subnet IDs
nlb_name = "my-boto3-nlb" nlb_tg_name = "my-boto3-nlb-tg"
try: # 1. Create NLB nlb_response = elbv2_client.create_load_balancer( Name=nlb_name, Subnets=subnet_ids, Scheme='internet-facing', Type='network', Tags=[ {'Key': 'Name', 'Value': nlb_name} ] ) nlb_arn = nlb_response['LoadBalancers'][0]['LoadBalancerArn'] print(f"Created NLB: {nlb_arn}")
# 2. Create Target Group for NLB nlb_tg_response = elbv2_client.create_target_group( Name=nlb_tg_name, Protocol='TCP', Port=8080, VpcId=vpc_id, HealthCheckProtocol='TCP', HealthCheckIntervalSeconds=10, HealthCheckTimeoutSeconds=6, HealthyThresholdCount=2, UnhealthyThresholdCount=2, Tags=[ {'Key': 'Name', 'Value': nlb_tg_name} ] ) nlb_tg_arn = nlb_tg_response['TargetGroups'][0]['TargetGroupArn'] print(f"Created NLB Target Group: {nlb_tg_arn}") # 3. Create Listener for NLB nlb_listener_response = elbv2_client.create_listener( LoadBalancerArn=nlb_arn, Protocol='TCP', Port=80, DefaultActions=[ { 'Type': 'forward', 'TargetGroupArn': nlb_tg_arn }, ] ) nlb_listener_arn = nlb_listener_response['Listeners'][0]['ListenerArn'] print(f"Created NLB Listener: {nlb_listener_arn}")except Exception as e: print(f"Error creating NLB resources: {e}") ```